home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 August: Technology Seed / ADC Seed CD - August 1999.toast / Carbon SDK 1.0d10c3 / Sample Code / AppearanceSample / FinderWindow.cp < prev    next >
Encoding:
Text File  |  1999-05-01  |  12.1 KB  |  435 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        FinderWindow.cp
  3.  
  4.     Contains:    Finder window simulating using the Appearance Manager.
  5.  
  6.     Version:    Appearance 1.0 SDK
  7.  
  8.     Copyright:    © 1997, 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                Edward Voas
  13.  
  14.         Other Contact:        7 of 9, Borg Collective
  15.  
  16.         Technology:            OS Technologies Group
  17.  
  18.     Writers:
  19.  
  20.         (jss)    Jeff Shulman
  21.         (edv)    Ed Voas
  22.  
  23.     Change History (most recent first):
  24.  
  25.        <1.8>      4/7/99    jss        Fix CarbonLib compilation problems
  26.          <1>     9/11/97    edv        First checked in.
  27. */
  28.  
  29. //
  30. //    This module demonstrates an Appearance adoption example for a Finder-like window.
  31. //    It uses actual Appearance Manager primitives to draw some of the window elements,
  32. //    such as the window header and placard. Normally, it would be best to use the
  33. //    window header and placard controls, since they take care of enabling and disabling
  34. //    themselves. This, however, is a good example of how to use lower level routines
  35. //    and still be theme savvy.
  36. //
  37. //    Although this window has scroll bars, it doesn't actually scroll anything. It's
  38. //    more an example of getting the visual appearance together.
  39. //
  40.  
  41. #include "AppearanceSamplePrefix.h"
  42.  
  43. #include <Appearance.h>
  44. #include <ControlDefinitions.h>
  45. #include <MacWindows.h>
  46. #include "FinderWindow.h"
  47. #include "Assertions.h"
  48.  
  49. #define width( r )        ( (r).right - (r).left )
  50. #define height( r )        ( (r).bottom - (r).top )
  51.  
  52. FinderWindow::FinderWindow() : BaseWindow( 128 )
  53. {                
  54.     Rect        rect;
  55.     
  56.         // Note the use of the new defProc constants here.
  57.         // This eliminates the need to go thru the mapping
  58.         // CDEF for scroll bars, which would normally happen
  59.         // after calling RegisterAppearanceClient.
  60.         
  61.     CalcVertScrollBarRect( rect );
  62.     CreateScrollBarControl( fWindow, &rect, 0, 0, 100, 0, false, nil, &fVertScrollBar );
  63.     
  64.     CalcHorizScrollBarRect( rect );
  65.     CreateScrollBarControl( fWindow, &rect, 0, 0, 100, 0, false, nil, &fHorizScrollBar );
  66. }
  67.  
  68. FinderWindow::~FinderWindow()
  69. {
  70.     if ( fVertScrollBar )
  71.         DisposeControl( fVertScrollBar );
  72.     
  73.     if ( fHorizScrollBar )
  74.         DisposeControl( fHorizScrollBar );
  75. }
  76.  
  77. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  78. //    Ä Activate
  79. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  80. //    Activates the contents of the window.
  81. //
  82. void
  83. FinderWindow::Activate( EventRecord& )
  84. {
  85.     Rect        rect;
  86.     
  87.     SetPort( fPort );
  88.     GetPortBounds( fPort, &rect );
  89.     InsetRect( &rect, -1, -1 );
  90.     rect.bottom = rect.top + 40;
  91.     ::DrawThemeWindowHeader( &rect, kThemeStateActive );
  92.     ValidWindowRect( fWindow, &rect );
  93.     
  94.     DrawPlacard( kThemeStateActive, true );
  95.  
  96.         // Here we use the new ActivateControl call. We
  97.         // could have still used HiliteControl, but this
  98.         // is much more straightforward. It also works
  99.         // right with and without embedding, so it's a
  100.         // real good idea to start using it.
  101.         
  102.     ActivateControl( fHorizScrollBar );
  103.     ActivateControl( fVertScrollBar );
  104. }
  105.  
  106. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  107. //    Ä Deactivate
  108. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  109. //    Deactivates the contents of the window.
  110. //
  111. void
  112. FinderWindow::Deactivate( EventRecord& )
  113. {
  114.     Rect        rect;
  115.     
  116.     SetPort( fPort );
  117.     GetPortBounds( fPort, &rect );
  118.     InsetRect( &rect, -1, -1 );
  119.     rect.bottom = rect.top + 40;
  120.     ::DrawThemeWindowHeader( &rect, kThemeStateDisabled );
  121.     ValidWindowRect( fWindow, &rect );
  122.     
  123.     DrawPlacard( kThemeStateDisabled, true );
  124.     
  125.         // Here we use the new DeactivateControl call. We
  126.         // could have still used HiliteControl, but this
  127.         // is much more straightforward. It also works
  128.         // right with and without embedding, so it's a
  129.         // real good idea to start using it.
  130.         
  131.     DeactivateControl( fHorizScrollBar );
  132.     DeactivateControl( fVertScrollBar );
  133. }
  134.  
  135. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  136. //    Ä Draw
  137. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  138. //    Draws our window. Appearance Manager calls handle multiple devices properly. We
  139. //    need to call DeviceLoop to handle drawing our list view, though.
  140. //
  141. void
  142. FinderWindow::Draw()
  143. {
  144.     Rect                    rect;
  145.     ThemeDrawState            drawState;
  146.     RgnHandle                rgn;
  147.     DeviceLoopDrawingUPP    proc;
  148.     
  149.         drawState = IsWindowHilited( fWindow ) ?
  150.                         (ThemeDrawState)kThemeStateActive :
  151.                         (ThemeDrawState)kThemeStateDisabled;
  152.  
  153.     rgn = NewRgn();
  154.     
  155.     if ( rgn )
  156.     {
  157.         ::SetPort( fPort );
  158.         ::GetPortBounds( fPort, &rect );
  159.         ::UpdateControls( fWindow, GetPortVisibleRegion( fPort, rgn ) );
  160.  
  161.         ::InsetRect( &rect, -1, -1 );
  162.         rect.bottom = rect.top + 40;
  163.         ::DrawThemeWindowHeader( &rect, drawState );
  164.  
  165.         GetContentRect( rect );
  166.  
  167.         RectRgn( rgn, &rect );
  168.  
  169.         proc = NewDeviceLoopDrawingProc( DrawListView );
  170.         DeviceLoop( rgn, proc, (long)this, 0 );
  171.         DisposeDeviceLoopDrawingUPP( proc );
  172.  
  173.         DisposeRgn( rgn );
  174.     }
  175.     DrawPlacard( drawState, false );
  176. }
  177.  
  178. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  179. //    Ä DrawListView
  180. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  181. //    Draws our list view columns, using the correct theme brushes.
  182. //
  183. pascal void
  184. FinderWindow::DrawListView( SInt16 depth, SInt16 flags, GDHandle /*device*/, long userData )
  185. {
  186.     FinderWindow*        window = (FinderWindow*)userData;
  187.     Rect                rect;
  188.     ThemeDrawingState    state;
  189.     SInt16                baseLine;
  190.     
  191.     window->GetContentRect( rect );
  192.     
  193.         // Because the brushes used by the Appearance Manager could
  194.         // be colors or patterns, our GetColorAndPenState routine
  195.         // always saves the current background pattern as well as the
  196.         // fore and back colors.
  197.         
  198.     ::GetThemeDrawingState( &state );
  199.  
  200.     ::SetThemeBackground( kThemeListViewBackgroundBrush, depth, (flags & gdDevType) != 0 );
  201.     ::EraseRect( &rect );
  202.     
  203.     rect.left += 40;
  204.     rect.right = rect.left + 120;
  205.     
  206.     ::SetThemeBackground( kThemeListViewSortColumnBackgroundBrush, depth, (flags & gdDevType) != 0 );
  207.     ::EraseRect( &rect );
  208.  
  209.     ::SetThemePen( kThemeListViewSeparatorBrush, depth, (flags & gdDevType) != 0 );
  210.  
  211.     window->GetContentRect( rect );
  212.     
  213.     for ( baseLine = rect.top; baseLine <= rect.bottom; baseLine += 15 )
  214.     {
  215.         ::MoveTo( rect.left, baseLine );
  216.         ::LineTo( rect.right - 1, baseLine );
  217.     }
  218.     
  219.     ::SetThemeDrawingState( state, true );
  220. }
  221.  
  222. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  223. //    Ä Resize
  224. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  225. //    Resize our window to the appropriate size specified in width and height. Make sure
  226. //    the scroll bars are repositioned properly.
  227. //
  228. void
  229. FinderWindow::Resize( SInt16 width, SInt16 height )
  230. {
  231.     Rect        horizRect, vertRect, bounds;
  232.     
  233.     GetPortBounds( fPort, &bounds );
  234.     if ( width > width( bounds ) )
  235.     {
  236.         bounds.left = bounds.right - 5;
  237.         bounds.bottom = 40;
  238.         InvalWindowRect( fWindow, &bounds );
  239.     }
  240.  
  241.     InvalidateScrollBars();
  242.     InvalidatePlacard();
  243.     
  244.     BaseWindow::Resize( width, height );
  245.     
  246.     InvalidateScrollBars();
  247.     InvalidatePlacard();
  248.     
  249.     CalcHorizScrollBarRect( horizRect );
  250.     CalcVertScrollBarRect( vertRect );
  251.     
  252.     MoveControl( fHorizScrollBar, horizRect.left, horizRect.top );
  253.     MoveControl( fVertScrollBar, vertRect.left, vertRect.top );
  254.     SizeControl( fHorizScrollBar, width( horizRect ), height( horizRect ) );
  255.     SizeControl( fVertScrollBar, width( vertRect ), height( vertRect ) );
  256. }
  257.  
  258. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  259. //    Ä HandleClick
  260. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  261. //    Simple routine to handle scroll bar tracking, even though they don't do anything.
  262. //
  263. void
  264. FinderWindow::HandleClick( EventRecord& event )
  265. {
  266.     ControlHandle        control;
  267.     SInt16                part;
  268.     Point                localPt;
  269.     ControlActionUPP    actionProc;
  270.     
  271.     SetPort( fPort );
  272.     localPt = event.where;
  273.     GlobalToLocal( &localPt );
  274.     
  275.     part = FindControl( localPt, fWindow, &control );
  276.     switch ( part )
  277.     {
  278.         case kControlUpButtonPart:
  279.         case kControlDownButtonPart:
  280.         case kControlPageUpPart:
  281.         case kControlPageDownPart:
  282.             actionProc = NewControlActionProc( ScrollBarAction );
  283.             TrackControl( control, localPt, actionProc );
  284.             DisposeControlActionUPP( actionProc );
  285.             break;
  286.         
  287.         case kControlIndicatorPart:
  288.             TrackControl( control, localPt, (ControlActionUPP)-1L );
  289.             break;
  290.     }
  291. }
  292.  
  293. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  294. //    Ä GetContentRect
  295. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  296. //    Get our content rect, which is the area not including the scroll bars and the
  297. //    window header. It is basically the list view area.
  298. //
  299. void
  300. FinderWindow::GetContentRect( Rect& rect )
  301. {
  302.     GetPortBounds( fPort, &rect );
  303.     
  304.     rect.bottom -= 15;
  305.     rect.right -= 15;
  306.     rect.top += 39;
  307. }
  308.  
  309. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  310. //    Ä DrawPlacard
  311. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  312. //    Draws our placard next to the horizontal scroll bar.
  313. //
  314. void
  315. FinderWindow::DrawPlacard( ThemeDrawState state, Boolean validate )
  316. {
  317.     Rect        rect;
  318.     
  319.     GetPortBounds( fPort, &rect );
  320.     
  321.     rect.bottom++;
  322.     rect.left--;
  323.     rect.top = rect.bottom - 16;
  324.     rect.right = 121;
  325.     
  326.     ::DrawThemePlacard( &rect, state );
  327.     if ( validate )
  328.         ValidWindowRect( fWindow, &rect );
  329. }
  330.  
  331. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  332. //    Ä InvalidateScrollBars
  333. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  334. //    Invalidates the scroll bar areas.
  335. //
  336. void
  337. FinderWindow::InvalidateScrollBars()
  338. {
  339.     Rect        tempRect;
  340.     
  341.     SetPort( fPort );
  342.     CalcHorizScrollBarRect( tempRect );
  343.     InvalWindowRect( fWindow, &tempRect );
  344.     EraseRect( &tempRect );
  345.     
  346.     CalcVertScrollBarRect( tempRect );
  347.     InvalWindowRect( fWindow, &tempRect );
  348.     EraseRect( &tempRect );
  349. }
  350.  
  351. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  352. //    Ä InvalidatePlacard
  353. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  354. //    Invalidates the placard area.
  355. //
  356. void
  357. FinderWindow::InvalidatePlacard()
  358. {
  359.     Rect        rect;
  360.     
  361.     GetPortBounds( fPort, &rect );
  362.     
  363.     rect.bottom++;
  364.     rect.top = rect.bottom - 16;
  365.     rect.right = 121;
  366.     rect.left--;
  367.  
  368.     InvalWindowRect( fWindow, &rect );
  369.     EraseRect( &rect );
  370. }
  371.  
  372. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  373. //    Ä CalcHorizScrollBarRect
  374. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  375. //    Calculates the position where the horizontal scroll bar should be placed.
  376. //
  377. void
  378. FinderWindow::CalcHorizScrollBarRect( Rect& rect )
  379. {
  380.     GetPortBounds( fPort, &rect );
  381.     rect.bottom++;
  382.     rect.left = rect.left + 120;
  383.     rect.top = rect.bottom - 16;
  384.     rect.right -= 14;
  385. }
  386.  
  387. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  388. //    Ä CalcVertScrollBarRect
  389. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  390. //    Calculates the position where the vertical scroll bar should be placed.
  391. //
  392. void
  393. FinderWindow::CalcVertScrollBarRect( Rect& rect )
  394. {
  395.     GetPortBounds( fPort, &rect );
  396.     rect.right++;
  397.     rect.left = rect.right - 16;
  398.     rect.bottom -= 14;
  399.     rect.top = 38;
  400. }
  401.  
  402. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  403. //    Ä ScrollBarAction
  404. //ãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã
  405. //    A simple callback to give some feedback when clicking the scroll arrows or page
  406. //    up/down areas.
  407. //
  408. pascal void
  409. FinderWindow::ScrollBarAction( ControlHandle control, SInt16 part )
  410. {
  411.     switch ( part )
  412.     {
  413.         case kControlUpButtonPart:
  414.             if ( GetControlValue( control) > GetControlMinimum( control ) )
  415.                 SetControlValue( control, GetControlValue( control ) - 1 );
  416.             break;
  417.         
  418.         case kControlDownButtonPart:
  419.             if ( GetControlValue( control) < GetControlMaximum( control ) )
  420.                 SetControlValue( control, GetControlValue( control ) + 1 );
  421.             break;
  422.             
  423.         case kControlPageUpPart:
  424.             if ( GetControlValue( control) > GetControlMinimum( control ) )
  425.                 SetControlValue( control, GetControlValue( control ) - 10 );
  426.             break;
  427.             
  428.         case kControlPageDownPart:
  429.             if ( GetControlValue( control) < GetControlMaximum( control ) )
  430.                 SetControlValue( control, GetControlValue( control ) + 10 );
  431.             break;
  432.     }            
  433. }
  434.  
  435.